#pragma once

#include <xpam/exception.h>

namespace xpam
{
    template<class T>
    class shared_ptr
    {
        T * _t;
        int * _c;
    public:
        shared_ptr() : _t(0), _c(0)
        { }

        explicit shared_ptr(const T * t)
        {
            _t = const_cast<T *>(t);
            _c = new int(0);
            _addref();
        }

        explicit shared_ptr(const shared_ptr & p)
        {
			_t = p._t;
			_c = p._c;
            _addref();
        }

        ~shared_ptr()
        {
            _release();
        }

        void operator = (const shared_ptr & p)
        {
            _release();
            _t = p._t;
            _c = p._c;
            _addref();
        }

        T * operator ->()
        {
            return _t;
        }

		T & operator *()
		{
			return *_t;
		}

		bool operator !()
		{
			return !(_t);
		}

        //operator T * ()
        //{
        //    return _t;
        //}

        T * get()
        {
            return _t;
        }
    private:
        void _addref()
        {
            if (_c != 0)
            {
            	(*_c)++;
            }
        }

        void _release()
        {
            if (_c != 0)
            {
            	(*_c)--;
                if ((*_c) == 0)
                {
                    delete _c, _c = 0;
                    delete _t, _t = 0;
                }
            }
        }
    };
}



